﻿using MyCompanyName.AbpZeroTemplate.Response;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyCompanyName.AbpZeroTemplate.Gantt
{
    [MetadataType(typeof(CalendarMetadata))]
    public partial class Calendar 
    {

        /// <summary>
        /// Parent node identifier.
        /// Used for more type flexible parent identifier processing since parentId provided
        /// from the client side may contain string value.
        /// So this property tries to convert string value to integer and sets it to `null` in case of failed attempt.
        /// </summary>
        [NotMapped]
        public virtual string parentId
        {
            set
            {
                // for root level nodes we keep `null`
                if (String.IsNullOrEmpty(value) || value.Equals("root", StringComparison.InvariantCultureIgnoreCase))
                {
                    parentIdRaw = null;
                    return;
                }

                try
                {
                    parentIdRaw = Convert.ToInt32(value);
                }
                catch (System.Exception)
                {
                    parentIdRaw = null;
                }
            }

            get
            {
                return !parentIdRaw.HasValue ? null : Convert.ToString(parentIdRaw.Value);
            }
        }

        /// <summary>
        /// Phantom parent identifier.
        /// </summary>
        [NotMapped]
        public virtual string PhantomParentId { get; set; }

        /// <summary>
        /// Used by `Newtonsoft.JSON` to exclude phantom parent identifier during entity serialization.
        /// </summary>
        /// <returns>false</returns>
        public bool ShouldSerializePhantomParentId() { return false; }

        [JsonIgnore]
        [NotMapped]
        public override String PhantomIdField { get { return "PhantomId"; } }

        [JsonProperty("PhantomId")]
        [NotMapped]
        public override string PhantomId { get; set; }


        [NotMapped]
        public IList<String> DefaultAvailability
        {
            set
            {
                if (value == null)
                {
                    DefaultAvailabilityRaw = null;
                    return;
                }

                DefaultAvailabilityRaw = String.Join("|", value);
            }

            get
            {
                return String.IsNullOrEmpty(DefaultAvailabilityRaw) ? null : DefaultAvailabilityRaw.Split('|');
            }
        }

        [NotMapped]
        public bool WeekendsAreWorkdays { get { return WeekendsAreWorkdaysRaw == 1; } }

        //<summary>
        //This property is used during serialization. It has calendar days collection.
        //</summary>
        [NotMapped]
        public LoadStoreResponse<CalendarDay> Days
        {
            get { return new LoadStoreResponse<CalendarDay>(CalendarDays); }
        }

        [NotMapped]
        public virtual bool leaf { get { return ChildrenRaw.Count == 0; } }

        [NotMapped]
        public virtual ICollection<Calendar> children
        {
            get { if (!leaf) return ChildrenRaw; return null; }
            set { ChildrenRaw = value; }
        }
    }

    public class CalendarMetadata : NodeMetadata<Calendar>
    {
        [JsonIgnore]
        public virtual ICollection<Calendar> ChildrenRaw { get; set; }
        [JsonIgnore]
        public string DefaultAvailabilityRaw { get; set; }
        [JsonIgnore]
        public Nullable<byte> WeekendsAreWorkdaysRaw { get; set; }
        [JsonIgnore]
        public virtual ICollection<CalendarDay> CalendarDays { get; set; }
        [JsonIgnore]
        public virtual ICollection<Task> Tasks { get; set; }
        [JsonIgnore]
        public virtual ICollection<Resource> Resources { get; set; }
    }
}
